import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * TimerPanel creates the screen on which the timer is run
 * @author Daniel Barg, Ivan Petrov
 *
 */

public class TimerPanel extends JPanel implements ActionListener{
    private MyFrame frame;
    private JLabel currentTime;
    private JLabel space;
    private Timer timer;
    private Toolkit toolkit;
    private int milliseconds;
    private int seconds;
    private int minutes;
    private int hours;
    private int startHours;
    private int startMinutes;
    private int startSeconds;
    private int startMilliseconds;
    private JPanel buttons;   
    private JButton tl;//top left, play/pause
    private boolean runOrNot;
    private JButton tr;//top right, stop
    private JButton bl;//bottom left, plus/minus
    private JButton br;//bottom right
    int counter;
    int totalMilliseconds=0;
    private int dispHours=0, dispMinutes=0, dispSeconds=0, dispMilliseconds=0;
    private boolean reachedZero;
    private Color previous;

    /**
     * constructor
     * @param myFrame
     */
    public TimerPanel(MyFrame myFrame) {
        frame=myFrame;
        reachedZero=false;
        this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        tl=new JButton(new ImageIcon("play.png"));
        tl.setToolTipText("play/pause");
        tr=new JButton(new ImageIcon("stop.png"));
        tr.setToolTipText("reset");
        bl=new JButton(new ImageIcon("plus_minus.png"));
        bl.setToolTipText("add/subtract extra time");
        br=new JButton(new ImageIcon("left.png"));
        br.setToolTipText("main menu");
        tl.addActionListener(this);
        runOrNot=true;
        tr.addActionListener(this);
        currentTime=new JLabel();
        currentTime.setAlignmentX(Component.CENTER_ALIGNMENT);
        Font times=new Font("Times",1,50);
        currentTime.setFont(times);
        this.add(currentTime);
        milliseconds=0;
        bl.addActionListener(this);
        br.addActionListener(this);
        buttons=new JPanel(new GridLayout(2,2));
        buttons.add(tl);
        buttons.add(tr);
        buttons.add(bl);
        buttons.add(br);
        this.add(buttons);
    }

    /**
     * class that runs the stopwatch
     * 
     */
    class TimingTask extends TimerTask{
        public void run() {
            String text=returnText();
            if(!reachedZero)
                currentTime.setText(text);
            milliseconds++;totalMilliseconds++;
            if(milliseconds==1000){
                milliseconds=0;
                seconds+=1;
                if(seconds==60){
                    seconds=0;
                    minutes+=1;
                }
                if(minutes==60){
                    minutes=0;
                    hours+=1;
                }
            }
        }
    }

    /**
     * actionPerformed method for buttons
     */
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==tl){
            if(!reachedZero){
                if(runOrNot==true){
                    runOrNot=false;
                    tl.setIcon(new ImageIcon("pause.png"));
                    toolkit = Toolkit.getDefaultToolkit();
                    timer = new Timer();
                    timer.schedule(new TimingTask(),0,1);
                }
                else{
                    runOrNot=true;
                    tl.setIcon(new ImageIcon("play.png"));
                    timer.cancel();
                }
            }
        }
        else{
            if(e.getSource()==tr){
                if(totalMilliseconds>0){
                    timer.cancel();
                    totalMilliseconds=0;
                    milliseconds=0;
                    seconds=0;
                    minutes=0;
                    hours=0;
                    counter=0;
                    currentTime.setText(returnText());
                    tl.setIcon(new ImageIcon("play.png"));
                    runOrNot=true;
                    if(reachedZero){
                        reachedZero=false;
                        currentTime.setForeground(previous);
                    }
                }
            }
            if(e.getSource()==bl){
                timer.cancel();
                counter++;
                milliseconds=0;
                seconds=0;
                minutes=0;
                hours=0;
                totalMilliseconds=0;
                frame.setTimer(dispHours, dispMinutes, dispSeconds);
                tl.setIcon(new ImageIcon("play.png"));
                runOrNot=true;
                if(reachedZero){
                    reachedZero=false;
                    currentTime.setForeground(previous);
                }
            }
            else{
                if(e.getSource()==br){
                    frame.mainMenu();
                    if(totalMilliseconds>0){
                        timer.cancel();
                        tl.setIcon(new ImageIcon("play.png"));
                        runOrNot=true;
                    }
                    if(reachedZero){
                        reachedZero=false;
                        currentTime.setForeground(previous);
                    }
                }
            }
        }
    }

    /**
     * timer method that resets the times
     * @param hoursNew
     * @param minutesNew
     * @param secondsNew
     */
    public void timer(int hoursNew, int minutesNew, int secondsNew){
        reachedZero=false;
        startHours=hoursNew;
        startMinutes=minutesNew;
        startSeconds=secondsNew;
        startMilliseconds=0;
        totalMilliseconds=0;
        hours=0;
        minutes=0;
        seconds=0;
        milliseconds=0;
        currentTime.setText(returnText());
        counter=0;
    }
    /**
     * sets background color
     * @param c
     */
    public void setColors(Color c){
        this.setBackground(c);
        tl.setBackground(c);
        tr.setBackground(c);
        bl.setBackground(c);
        br.setBackground(c);
        currentTime.setBackground(c);
        currentTime.setForeground(frame.getOpposite(c));
    }
    
    /**
     * returns the text on the screen
     * @return text
     */
    public String returnText(){
        if(totalMilliseconds!=0){
            dispHours=startHours-hours;
            if(startMinutes-minutes>=0)
                dispMinutes=startMinutes-minutes;
            else{
                if(dispHours>0)
                    dispHours--;
                else
                    dispHours=59;
                dispMinutes=60-(minutes-startMinutes);
            }
            if(startSeconds-seconds>0)
                dispSeconds=startSeconds-seconds;
            else{
                if(dispMinutes>0)
                    dispMinutes--;
                else{
                    dispMinutes=59;
                    if(dispHours>0)dispHours--;
                }
                dispSeconds=60-(seconds-startSeconds);
            }
            if(startMilliseconds-milliseconds>=0)
                dispMilliseconds=startMilliseconds-milliseconds;
            else{
                if(dispSeconds>0)
                    dispSeconds--;
                else{
                    if(dispMinutes==0){
                        dispMinutes=59;
                        if(dispHours>0)
                            dispHours--;
                    }
                    dispSeconds=59;
                    if(dispMinutes>0)dispMinutes--;
                }
                dispMilliseconds=1000-(milliseconds-startMilliseconds);
            }
        }
        else{
            dispHours=startHours;
            dispMinutes=startMinutes;
            dispSeconds=startSeconds;
            dispMilliseconds=startMilliseconds;
        }
        String text="";
        if(((Integer)dispHours).toString().length()==1)
            text="0"+dispHours;
        else text=""+dispHours;
        text+=":";
        if(((Integer)dispMinutes).toString().length()==1)
            text+="0"+dispMinutes;
        else text+=""+dispMinutes;
        text+=":";
        if(((Integer)dispSeconds).toString().length()==1)
            text+="0"+dispSeconds;
        else text+=""+dispSeconds;
        text+=":";
        if(((Integer)dispMilliseconds).toString().length()==1)
            text+="00"+dispMilliseconds;
        else
            if(((Integer)dispMilliseconds).toString().length()==2)
                text+="0"+dispMilliseconds;
            else text+=""+dispMilliseconds;
        reachedZero();
        return text;
    }
    
    /**
     * method to check if time has reached zero
     */
    private void reachedZero() {
        if(dispHours==0&&dispMinutes==0&&dispSeconds==0&&dispMilliseconds==1){
            reachedZero=true;
            timer.cancel();
            currentTime.setText("00:00:00:000");
            previous=currentTime.getForeground();
            currentTime.setForeground(Color.red);
            tl.setIcon(new ImageIcon("play.png"));
            runOrNot=true;
        }
    }

}


